﻿using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.IdentityModel.Tokens;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Security.Claims;
using System.Threading.Tasks;
using TomNet.AspNetCore.Data;
using TomNet.Core;
using TomNet.Core.Options;

namespace TomNet.App.Web.Common
{
	public class ApiAuthenticationAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext context)
        {
            if (context.ActionDescriptor.FilterDescriptors.Any(p=>p.Filter is AllowAnonymousAttribute))
            {
                base.OnActionExecuting(context);
            }
            else
            {
                try
                {
                    string token = context.HttpContext.Request.Headers.ContainsKey("Token") ? context.HttpContext.Request.Headers["Token"].ToString() : "";
                    if (!string.IsNullOrWhiteSpace(token))
                    {
                        TomNetOptions options = context.HttpContext.RequestServices.GetTomNetOptions();
                        JwtOptions jwtOptions = options.Jwt;

                        System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler tokenHandler = new System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler();
                        var symmetricKey = System.Text.Encoding.ASCII.GetBytes(jwtOptions.Secret);
                        var validationParameters = new TokenValidationParameters()
                        {
                            RequireExpirationTime = true, //token是否包含有效期
                            ValidateIssuer = false, //验证秘钥发行人，如果要验证在这里指定发行人字符串即可
                            ValidateAudience = false, //验证秘钥的接受人，如果要验证在这里提供接收人字符串即可
                            IssuerSigningKey = new SymmetricSecurityKey(symmetricKey) //生成token时的安全秘钥
                        };

                        SecurityToken securityToken;
                        ClaimsPrincipal principal = tokenHandler.ValidateToken(token, validationParameters, out securityToken);

                        ClaimsIdentity identity = principal?.Identity as ClaimsIdentity;
                        if (identity != null && identity.IsAuthenticated)
                        {
                            string data = identity.FindFirst(ClaimTypes.NameIdentifier)?.Value;
                            int.TryParse(data, out int userId);

                            if (userId > 0)
                            {
                                base.OnActionExecuting(context);
                            }
                            else
                            {
                                AjaxResult result = new AjaxResult("Unauthorized", Data.AjaxResultType.UnAuth);
                                context.Result = new JsonResult(result);
                            }
                        }
                        else
                        {
                            AjaxResult result = new AjaxResult("Unauthorized", Data.AjaxResultType.UnAuth);
                            context.Result = new JsonResult(result);
                        }
                    }
                    else
                    {
                        AjaxResult result = new AjaxResult("Unauthorized", Data.AjaxResultType.UnAuth);
                        context.Result = new JsonResult(result);
                    }
                }
                catch
                {
                    AjaxResult result = new AjaxResult("InternalServerError", Data.AjaxResultType.Error);
                    context.Result = new JsonResult(result);
                }
            }

            base.OnActionExecuting(context);
        }
        
        public virtual bool ValidateToken(string token)
        {
            return token == "tommy";
        }
    }
}
